# -*- coding: utf-8 -*-
from functools import reduce

import sys

reload(sys)
sys.setdefaultencoding('utf-8')

import json

from decimal import *
from datetime import *
import dateutil.parser
from django.utils import formats
from django.db.models import Q

import operator
# from django.core.serializers import json
from django.db import models
from django.db.models.fields.related import RelatedField
from django.core.exceptions import FieldError, ImproperlyConfigured, FieldDoesNotExist
from django.core.paginator import Paginator, InvalidPage
from django.utils.encoding import smart_str
import logging

logger = logging.getLogger("django")


class XJsonEncoder(json.JSONEncoder):
	def default(self, obj):
		if isinstance(obj, datetime):
			return obj.strftime('%Y-%m-%d %H:%M:%S')
		elif isinstance(obj, date):
			return obj.strftime('%Y-%m-%d')
		elif isinstance(obj, Decimal):
			# return str(obj)
			return float(obj)
		elif isinstance(str, unicode):
			return obj
		else:
			return json.JSONEncoder.default(self, obj)


# def default(self, o):
# 	# See "Date Time String Format" in the ECMA-262 specification.
# 	if isinstance(o, datetime.datetime):
# 		r = o.isoformat()
# 		if o.microsecond:
# 			r = r[:23] + r[26:]
# 		if r.endswith('+00:00'):
# 			r = r[:-6] + 'Z'
# 		return r
# 	elif isinstance(o, datetime.date):
# 		return o.isoformat()
# 	elif isinstance(o, datetime.time):
# 		if is_aware(o):
# 			raise ValueError("JSON can't represent timezone-aware times.")
# 		r = o.isoformat()
# 		if o.microsecond:
# 			r = r[:12]
# 		return r
# 	elif isinstance(o, datetime.timedelta):
# 		return duration_iso_string(o)
# 	elif isinstance(o, decimal.Decimal):
# 		return str(o)
# 	elif isinstance(o, uuid.UUID):
# 		return str(o)
# 	elif isinstance(o, Promise):
# 		return six.text_type(o)
# 	elif isinstance(o, CallableBool):
# 		return bool(o)
# 	else:
# 		return super(DjangoJSONEncoder, self).default(o)

def json_encode(data):
	# encoder = json.DjangoJSONEncoder()
	# return encoder.encode(data)
	return json.dumps(data, cls=XJsonEncoder)


# Dispathcer
class FieldDispatcher(object):
	_relationship_fields = ['ForeignKey']

	def convert_field_to_js(self, model, field, data_type, field_value):
		try:
			field_class = getattr(sys.modules[__name__], data_type)
			if not data_type in self._relationship_fields:
				return field_class().convert_field_to_js(field_value)
			else:
				return field_class().convert_field_to_js(model, field, field_value)
		except Exception as e:
			raise NotImplementedError(e)

	def convert_field_to_model(self, model, field, data_type, field_value):
		try:
			field_class = getattr(sys.modules[__name__], data_type)
			if not data_type in self._relationship_fields:
				return field_class().convert_field_to_model(field_value)
			else:
				return field_class().convert_field_to_model(model, field, field_value)
		except Exception as e:
			raise NotImplementedError(e)

	def get_search_options(self, data_type):
		try:
			field_class = getattr(sys.modules[__name__], data_type)
			return field_class().get_search_options()
		except Exception as e:
			raise NotImplementedError(e)

	def get_format_options(self, data_type):
		try:
			field_class = getattr(sys.modules[__name__], data_type)
			return field_class().get_format_options()
		except Exception as e:
			raise NotImplementedError(e)


######################### Design Pattern ###########################

# Interface:

class Field(object):
	def convert_field_to_js(self, field_value):
		pass

	def convert_field_to_model(self, field_value):
		pass

	def get_search_options(self):
		pass

	def get_format_options(self):
		pass


# Interface Relationship Fields:
class RelationShipField(object):
	def convert_field_to_js(self, model, field, field_value):
		pass

	def convert_field_to_model(self, model, field, field_value):
		pass

	def get_search_options(self):
		pass

	def get_format_options(self):
		pass


# Concrete Fields:

class IntegerField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return int(value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for IntegerField
		"""
		return False, ""


class BigIntegerField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return int(value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for BigIntegerField
		"""
		return False, ""


class PositiveIntegerField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return int(value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for PositiveIntegerField
		"""
		return False, ""


class SmallIntegerField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return int(value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for SmallIntegerField
		"""
		return False, ""


class DecimalField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return Decimal(value)

		except Exception as e:
			raise InvalidOperation(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for DecimalField
		"""
		return False, ""


class FloatField(Field):
	def convert_field_to_js(self, field_value):
		return str(field_value)

	def convert_field_to_model(self, value):
		try:
			return float(value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for FloatField
		"""
		return False, ""


class DateField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return field_value.strftime(formats.date_format(field_value, "SHORT_DATETIME_FORMAT"))

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return dateutil.parser.parse(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for DateField
		"""
		return False, ""


class TimeField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return field_value.strftime(formats.date_format(field_value, "SHORT_DATETIME_FORMAT"))

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return dateutil.parser.parse(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for TimeField
		"""
		return False, ""


class DateTimeField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return field_value.strftime(formats.date_format(field_value, "SHORT_DATETIME_FORMAT"))

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return dateutil.parser.parse(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", "lt", "le", "gt", "ge"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for DateTimeField
		"""
		return False, ""


class CharField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["bw", "bn", "in", "ni", "ew", "en", "cn", "nc"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for CharField
		"""
		return False, ""


class TextField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["bw", "bn", "in", "ni", "ew", "en", "cn", "nc"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for TextField
		"""
		return False, ""


class BooleanField(Field):
	_affirmative_response = 'Yes'
	_negative_response = 'No'
	_list_affirmative_responses = ['yes', 'si', 'oui', 'da', 'ja']

	def convert_field_to_js(self, field_value):
		if field_value:
			return self._affirmative_response
		else:
			return self._negative_response

	def convert_field_to_model(self, field_value):
		if field_value.lower() in self._list_affirmative_responses:
			return True
		else:
			return False

	def get_search_options(self):
		return {"sopt": ["eq", "ne", ]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for BooleanField
		"""
		return False, ""


class EmailField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["bw", "bn", "in", "ni", "ew", "en", "cn", "nc"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for EmailField
		formatter: 'email', ""
		"""
		return "email", ""


class URLField(Field):
	def convert_field_to_js(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, field_value):
		try:
			return str(field_value)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["bw", "bn", "in", "ni", "ew", "en", "cn", "nc"]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for URLField
		formatter: 'link',
		"""
		return "link", {"target": "_blank"}


# Concrete Relationship Fields

class ForeignKey(RelationShipField):
	def convert_field_to_js(self, model, field, field_value):
		try:
			return getattr(model.objects.filter(Q(**{field: field_value}))[0], field).__unicode__()

		except Exception as e:
			raise ValueError(e)

	def convert_field_to_model(self, model, field, field_value):
		try:
			return model._meta.get_field(field).rel.to.objects.get(
				Q(**{model._meta.get_field(field).rel.to._meta.jqgrid_related_field: field_value})
			)

		except Exception as e:
			raise ValueError(e)

	def get_search_options(self):
		return {"sopt": ["eq", "ne", ]}

	def get_format_options(self):
		"""
		Return the formatter and formatoptions string for ForeignKey
		"""
		return False, ""


class JqGrid(object):
	queryset = None
	model = None
	fields = []
	allow_empty = True
	extra_config = {}

	pager_id = '#grid-pager'
	# 获取数据的地址
	url = ""
	# 编辑的地址
	editurl = ""
	caption = None
	colmodel_overrides = {}

	def get_queryset(self, request):
		if hasattr(self, 'queryset') and self.queryset is not None:
			queryset = self.queryset._clone()
		elif hasattr(self, 'model') and self.model is not None:
			queryset = self.model.objects.all()  # formerly: values(*self.get_field_names())
		else:
			raise ImproperlyConfigured("No queryset or model defined.")
		self.queryset = queryset
		return self.queryset

	def get_model(self):
		if hasattr(self, 'model') and self.model is not None:
			model = self.model
		elif hasattr(self, 'queryset') and self.queryset is not None:
			model = self.queryset.model
			self.model = model
		else:
			raise ImproperlyConfigured("No queryset or model defined.")
		return model

	def get_items(self, request):
		items = self.get_queryset(request)
		items = self.filter_items(request, items)
		items = self.sort_items(request, items)
		paginator, page, items = self.paginate_items(request, items)
		return paginator, page, items

	def get_filters(self, request):
		_search = request.GET.get('_search')
		filters = None
		# multiple field search
		_filters = request.GET.get('filters', '')
		if _filters:
			try:
				filters = json.loads(_filters)
			except ValueError:
				return None

		else:
			field = request.GET.get('searchField')
			op = request.GET.get('searchOper')
			data = request.GET.get('searchString')

			# single field search
			if all([field, op, data]):
				filters = {
					'groupOp': 'AND',
					'rules': [{'op': op, 'field': field, 'data': data}]
				}

		# toolbar search - this may work in addition to field searches
		field_names = [f.name for f in self.get_model()._meta.local_fields]
		if not filters:
			filters = {
				'groupOp': 'AND',
				'rules': []
			}
		for param in request.GET:
			if param in field_names:
				filters['rules'] += [{'op': 'cn', 'field': param, 'data': request.GET[param]}]

		return filters

	def filter_items(self, request, items):
		# TODO: Add option to use case insensitive filters
		# TODO: Add more support for RelatedFields (searching and displaying)
		# FIXME: Validate data types are correct for field being searched.
		filter_map = {
			# jqgrid op: (django_lookup, use_exclude)
			'ne': ('%(field)s__exact', True),
			'bn': ('%(field)s__startswith', True),
			'en': ('%(field)s__endswith', True),
			'nc': ('%(field)s__contains', True),
			'ni': ('%(field)s__in', True),
			'in': ('%(field)s__in', False),
			'eq': ('%(field)s__exact', False),
			'bw': ('%(field)s__startswith', False),
			'gt': ('%(field)s__gt', False),
			'ge': ('%(field)s__gte', False),
			'lt': ('%(field)s__lt', False),
			'le': ('%(field)s__lte', False),
			'ew': ('%(field)s__endswith', False),
			'cn': ('%(field)s__contains', False)
		}
		if self.get_config(False)['ignoreCase']:
			filter_map.update({
				'ne': ('%(field)s__iexact', True),
				'eq': ('%(field)s__iexact', False),
				'bn': ('%(field)s__istartswith', True),
				'bw': ('%(field)s__istartswith', False),
				'en': ('%(field)s__iendswith', True),
				'ew': ('%(field)s__iendswith', False),
				'nc': ('%(field)s__icontains', True),
				'cn': ('%(field)s__icontains', False)
			}
			)
		_filters = self.get_filters(request)
		if not _filters or not _filters.get('rules'):
			return items

		q_filters = []
		for rule in _filters['rules']:
			op, field, data = rule['op'], rule['field'], rule['data']
			# FIXME: Restrict what lookups performed against RelatedFields

			# 这里方法关联的外键字段值只有关联表中的字段名字
			real_field_name = field  # 本表中的字段名
			other_field_name = ""  # 关联表中的字段名称
			for field_name in self.fields:
				if field_name.endswith("__%s" % (field,)):
					logger.info(u"字段[%s]转换为[%s],为关联外键字段" % (field, field_name))
					real_field_name = field_name
					field = field_name
					op = 'eq'
					logger.info(u"字段[%s]为关联字段强制设置op为[%s]" % (field, op))
					break

			# field_class = self.get_model()._meta.get_field(real_field_name)
			# if isinstance(field_class, RelatedField):
			# 	op = 'eq'
			# 	# # 从关联表中查询字段
			# 	# kwargs = {}
			# 	# kwargs[other_field_name] = data
			# 	# logger.info(u"%s" % (dir(field_class),))
			# 	# logger.info(u"查询 to_fields：%s" % (field_class.to_fields,))
			# 	# logger.info(u"查询 db_column：%s" % (field_class.db_column,))
			# 	# logger.info(u"关联的模型：%s,查找条件为[%s]" % (field_class.rel.to, kwargs))
			# 	# ret = field_class.rel.to.objects.get(**kwargs)
			# 	# logger.info(u"查询的结果为：%s" % (ret,))
			# 	# 查看文档，更多相关信息http://python.usyiyi.cn/documents/django_182/topics/db/queries.html#field-lookups
			# 	logger.info(u"字段[%s]为关联字段强制设置op为[%s]" % (field, op))

			logger.info(u"查询 字段：%s %s %s" % (field, op, data))
			filter_fmt, exclude = filter_map[op]
			filter_str = smart_str(filter_fmt % {'field': field})
			if filter_fmt.endswith('__in'):
				filter_kwargs = {filter_str: data.split(',')}
			else:
				filter_kwargs = {filter_str: smart_str(data)}

			if exclude:
				q_filters.append(~models.Q(**filter_kwargs))
			else:
				q_filters.append(models.Q(**filter_kwargs))

		if _filters['groupOp'].upper() == 'OR':
			filters = reduce(operator.ior, q_filters)
		else:
			filters = reduce(operator.iand, q_filters)
		return items.filter(filters)

	@staticmethod
	def sort_items(request, items):
		sidx = request.GET.get('sidx')
		if sidx is not None:
			order_by_list = []
			sord = request.GET.get('sord')
			sidx_list = map(lambda x: x.strip(), sidx.split(','))
			for item in sidx_list:
				ordering = item.split(' ')
				if len(ordering) > 1:
					order_by = u"{0}{1}".format(ordering[1] == 'desc' and '-' or '', ordering[0])
				else:
					order_by = u"{0}{1}".format(sord == 'desc' and '-' or '', ordering[0])
				order_by_list.append(order_by)
			try:
				items = items.order_by(*order_by_list)
			except FieldError:
				pass
		return items

	def get_paginate_by(self, request):
		rows = request.GET.get('rows', self.get_config(False)['rowNum'])
		try:
			paginate_by = int(rows)
		except ValueError:
			paginate_by = 10
		return paginate_by

	def paginate_items(self, request, items):
		paginate_by = self.get_paginate_by(request)
		if not paginate_by:
			return None, None, items

		paginator = Paginator(items, paginate_by, allow_empty_first_page=self.allow_empty)
		page = request.GET.get('page', 1)

		try:
			page_number = int(page)
			page = paginator.page(page_number)
		except (ValueError, InvalidPage):
			page = paginator.page(1)
		return paginator, page, page.object_list

	def get_json(self, request):
		paginator, page, items = self.get_items(request)
		field_names = list(self.get_field_names())
		if 'myac' in field_names:
			field_names.remove('myac')

		items = items.values(*field_names) if items.count() > 0 else []
		data = {
			'page': int(page.number),
			'total': int(paginator.num_pages),
			'rows': [obj for obj in items],
			'records': int(paginator.count),
		}
		return json_encode(data)

	def get_default_config(self):
		config = {
			'datatype': 'json',
			'autowidth': True,
			'forcefit': True,
			'ignoreCase': True,
			'shrinkToFit': True,
			'jsonReader': {'repeatitems': False},
			'rowNum': 10,
			'rowList': [10, 25, 50, 100],
			'sortname': 'id',
			'viewrecords': True,
			'sortorder': "desc",
			'pager': self.pager_id,
			'altRows': True,
			'gridview': True,
			'height': 'auto',

			# 'multikey': 'ctrlKey',
			'multiboxonly': False,
			'multiselect': False,
			# 'toolbar': [False, 'bottom'],
			# 'userData': None,
			'rownumbers': True,
			"editurl": self.editurl,
		}
		return config

	def get_url(self):
		return str(self.url)

	def get_caption(self):
		if self.caption is None:
			opts = self.get_model()._meta
			self.caption = opts.verbose_name_plural.capitalize()
		return self.caption

	def get_config(self, as_json=True):
		config = self.get_default_config()
		config.update(self.extra_config)
		config.update({
			'url': self.get_url(),
			'caption': self.get_caption(),
			'colModel': self.get_colmodels(),
		})
		if as_json:
			config = json_encode(config)
		return config

	def lookup_foreign_key_field(self, options, field_name):
		"""Make a field lookup converting __ into real models fields"""
		if '__' in field_name:
			fk_name, field_name = field_name.split('__', 1)
			# print type(options), type(options.model)
			# print fk_name

			field_class = getattr(options.model, fk_name)
			# print type(field_class), field_class
			if not field_class:
				raise FieldError('No field %s in %s' % (fk_name, options))
			if hasattr(field_class, "field"):
				foreign_model_options = field_class.field.related_model._meta
			elif hasattr(field_class, "related"):
				foreign_model_options = field_class.related.related_model._meta

			# fields = [f for f in options.fields if f.name == fk_name]
			# if len(fields) > 0:
			# 	field_class = fields[0]
			# else:
			# 	raise FieldError('No field %s in %s' % (fk_name, options))
			# foreign_model_options = field_class.rel.to._meta
			return self.lookup_foreign_key_field(foreign_model_options, field_name)
		else:
			return options.get_field(field_name)

	def get_colmodels(self):
		colmodels = []
		opts = self.get_model()._meta
		for field_name in self.get_field_names():
			try:
				field = self.lookup_foreign_key_field(opts, field_name)
				colmodel = self.field_to_colmodel(field, field_name)
			except FieldDoesNotExist:
				colmodel = {
					'name': field_name,
					'index': field_name,
					'label': field_name,
					'editable': False
				}
			override = self.colmodel_overrides.get(field_name)

			if override:
				colmodel.update(override)
			colmodels.append(colmodel)
		return colmodels

	def get_field_names(self):
		fields = self.fields
		if not fields:
			fields = [f.name for f in self.get_model()._meta.local_fields]
		return fields

	@staticmethod
	def field_to_colmodel(field, field_name):
		colmodel = {
			'name': field_name,
			'index': field.name,
			'label': str(field.verbose_name),
			'editable': True
		}
		return colmodel

	def add_object(self, request):
		"""
		jqGrid add method control. Add a new object into model.
		Return the new object created.
		"""
		try:
			modelCls = self.get_model()
			new_object = modelCls()

			for field in self.model._meta.fields:
				field_name = field.attname
				field_value = request.POST.get(field_name)
				if field_value is None:
					continue
				data_type = field.get_internal_type()
				if data_type in ('AutoField', 'BigAutoField'):
					# 自动增长的类型不能够修改
					continue
				value = self.convert_data(data_type, field_value)
				setattr(new_object, field_name, value)
				logger.info(u"设置属性[%s]=(%s)[%s]" % (field_name, type(value), value))

			new_object.save()
			return True
		except Exception as e:
			logger.exception(u"添加失败")

		return False

	def edit_object(self, request, object_id):
		"""
		编辑对象
		"""
		try:
			modelCls = self.get_model()
			object_for_update = modelCls.objects.get(id=object_id)

			for field in modelCls._meta.fields:
				field_name = field.attname
				field_value = request.POST.get(field_name)
				if field_value is None:
					continue
				data_type = field.get_internal_type()
				if data_type in ('AutoField', 'BigAutoField'):
					# 自动增长的类型不能够修改
					continue
				value = self.convert_data(data_type, field_value)
				setattr(object_for_update, field_name, value)
				logger.info(u"设置属性[%s]=(%s)[%s]" % (field_name, type(value), value))
			object_for_update.save()
			return True
		except Exception as e:
			logger.exception(u"编辑失败")

		return False

	def delete_object(self, request, object_id):
		"""
		Delete an object identified by id from model
		Return True or False if the oper has been accomplished
		"""
		try:
			modelCls = self.get_model()
			modelCls.objects.get(id=object_id).delete()
			return True
		except Exception as e:
			return False

	def convert_data(self, data_type, field_value):
		# for x in ('AutoField', 'BLANK_CHOICE_DASH', 'BigAutoField', 'BigIntegerField',
		# 		'BinaryField', 'BooleanField', 'CharField', 'CommaSeparatedIntegerField',
		# 		'DateField', 'DateTimeField', 'DecimalField', 'DurationField',
		# 		'EmailField', 'Empty', 'Field', 'FieldDoesNotExist', 'FilePathField',
		# 		'FloatField', 'GenericIPAddressField', 'IPAddressField', 'IntegerField',
		# 		'NOT_PROVIDED', 'NullBooleanField', 'PositiveIntegerField',
		# 		'PositiveSmallIntegerField', 'SlugField', 'SmallIntegerField', 'TextField',
		# 		'TimeField', 'URLField', 'UUIDField',):
		try:
			if data_type in ('AutoField', 'IntegerField', 'PositiveIntegerField', 'PositiveSmallIntegerField', 'SmallIntegerField'):
				return int(field_value)
			elif data_type in ('BigAutoField', 'BigIntegerField',):
				return long(field_value)
			elif data_type in ('DateField', 'DateTimeField', 'TimeField'):
				return dateutil.parser.parse(field_value)
			elif data_type in ('DecimalField',):
				return Decimal(field_value)
			elif data_type in ('FloatField',):
				return float(field_value)
			elif data_type in ('BooleanField',):
				v = field_value.lower()
				if v == 'true':
					return True
				else:
					return False
			elif data_type in ('NullBooleanField',):
				v = field_value.lower()
				if v in ('true', 'false', 'null'):
					if v == 'true':
						return True
					elif v == 'false':
						return False
					else:
						return None
			else:
				return field_value

		except Exception as e:
			raise ValueError(e)
